﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace Plugins.StateMachines
{
    public delegate T Factory<T>();
    public class PluginEnumerator<T> : IEnumerable<T>, IEnumerator<T>
    {
        private Factory<IEnumerable<T>> _action;
        private IEnumerable<T> _enumerable;
        private IEnumerator<T> _enumerator;
        private T _value;

        protected PluginEnumerator() { }
        public PluginEnumerator(Factory<IEnumerable<T>> action)
        {
            _action = action;
        }

        IEnumerator<T> IEnumerable<T>.GetEnumerator() { return this; }
        IEnumerator IEnumerable.GetEnumerator() { return this; }

        void IDisposable.Dispose() { }

        T IEnumerator<T>.Current { get { return _value; } }
        object IEnumerator.Current { get { return _value; } }
        bool IEnumerator.MoveNext()
        {
            if (_enumerable == null)
            {
                if (_action != null)
                {
                    try
                    {
                        _enumerable = _action();
                    }
                    catch (Exception)
                    {
                        return false;
                    }
                }
                if (_enumerable == null) return false;
                _enumerator = _enumerable.GetEnumerator();
            }
            if (_enumerator == null) return false;
            if (_enumerator.MoveNext())
            {
                _value = _enumerator.Current;
                return true;
            }
            _enumerator.Reset();
            return false;
        }
        void IEnumerator.Reset()
        {
            _enumerable = null;
            _value = default(T);
        }
    }
}
